package com.summer.data.jql.builder;

import com.summer.data.Jql;
import com.summer.data.jql.behavior.FilterAble;
import com.summer.data.jql.behavior.OrderAble;
import com.summer.data.jql.behavior.SelectAble;
import com.summer.data.jql.behavior.TableAble;
import com.summer.data.rs.datatype.PageInfo;
import com.summer.data.table.BaseTable;
import com.summer.data.type.Linker;

public class JqlLinker extends Jql {

    static class LinkType {

        public static LinkType UNION = new LinkType("UNION");
        public static LinkType UNION_ALL = new LinkType("UNION ALL");
        public static LinkType INTERSECT = new LinkType("INTERSECT");
        public static LinkType MINUS = new LinkType("MINUS");
        public static LinkType EXCEPT = new LinkType("EXCEPT");

        private String type;

        private LinkType(String type) {
            this.type = type;
        }
    }

    private Linker<Jql, LinkType> linker = new Linker<>();

    private PageInfo pageInfo = PageInfo.get();

    public void add(Jql jql) {
        linker.add(jql);
    }

    public Jql distinct() {
        linker.last().distinct();
        return this;
    }

    public Jql select(SelectAble... exps) {
        linker.last().select(exps);
        return this;
    }

    public Jql select(BaseTable table) {
        linker.last().select(table);
        return this;
    }

    // public Query select(int val) {
    // return this;
    // }

    // public Query select(String val) {
    // return this;
    // }

    public Jql from(TableAble queryAble) {
        linker.last().from(queryAble);
        return this;
    }

    public Jql join(TableAble queryAble) {
        linker.last().join(queryAble);
        return this;
    }

    public Jql leftJoin(TableAble queryAble) {
        linker.last().leftJoin(queryAble);
        return this;
    }

    public Jql on(FilterAble... exps) {
        linker.last().on(exps);
        return this;
    }

    public Jql where() {
        linker.last().where();
        return this;
    }

    public Jql where(FilterAble... exps) {
        linker.last().where(exps);
        return this;
    }

    public Jql and(FilterAble exp) {
        linker.last().and(exp);
        return this;
    }

    public Jql or(FilterAble exp) {
        linker.last().or(exp);
        return this;
    }

    // public BoolExpression andPack(BoolExpression... exps) {
    // return new AndPack(exps);
    // }

    public Jql order(OrderAble... exps) {
        linker.last().order(exps);
        return this;
    }

    /**
     * 并集
     * 
     * @param another 另一个数据集
     * @return this
     */
    public Jql union(Jql another) {
        linker.addR(LinkType.UNION);
        linker.add(another);
        return this;
    }

    // 并集
    public Jql unionAll(Jql another) {
        linker.addR(LinkType.UNION_ALL);
        linker.add(another);
        return this;
    }

    // 交集
    public Jql interSect(Jql another) {
        linker.addR(LinkType.INTERSECT);
        linker.add(another);
        return this;
    }

    // 差集，返回两个结果集中不同的部分
    // oracle 支持
    public Jql minus(Jql another) {
        linker.addR(LinkType.MINUS);
        linker.add(another);
        return this;
    }

    // 从左结果集中去掉在右结果集中出现的后返回
    // mysql 不支持
    public Jql except(Jql another) {
        linker.addR(LinkType.EXCEPT);
        linker.add(another);
        return this;
    }

    public void page(Integer pageNo, Integer pageSize) {
        assert pageNo > 0;
        assert pageSize > 0;
        this.pageInfo = new PageInfo(pageNo, pageSize);
    }

    public PageInfo getPageInfo() {
        return pageInfo;
    }

}
